package com.bringspring.system.permission.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bringspring.common.base.UserInfo;
import com.bringspring.common.util.DateUtil;
import com.bringspring.common.util.RandomUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.UserProvider;
import com.bringspring.system.permission.constant.PermissionConst;
import com.bringspring.system.permission.entity.*;
import com.bringspring.system.permission.mapper.UserRelationMapper;
import com.bringspring.system.permission.model.permission.PermissionModel;
import com.bringspring.system.permission.model.userrelation.UserRelationForm;
import com.bringspring.system.permission.service.*;
import com.bringspring.system.permission.util.PermissionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户关系
 *
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2017年9月26日 上午9:18
 */
@Service
@DSTransactional
public class UserRelationServiceImpl extends ServiceImpl<UserRelationMapper, UserRelationEntity> implements UserRelationService {

    @Autowired
    private UserProvider userProvider;
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PositionService positionService;
    @Autowired
    private OrganizeService organizeService;
    @Autowired
    private OrganizeRelationService organizeRelationService;
    @Autowired
    private UserRelationService userRelationService;

    @Override
    public UserRelationEntity createAuthorizeAddress(List<String> address,List<String> userId) {
        UserInfo userInfo = userProvider.get();
        String collect = "";
        UserRelationEntity userRelationEntity = new UserRelationEntity();
        if (ObjectUtil.isNotEmpty(address)) {
            String[] addressStr = address.toArray(new String[]{});
            List<String> list1 = new ArrayList<>();
            for (String s : addressStr) {
                list1.add(s);
            }
            collect = list1.stream().map((s) -> "\"" + s + "\"").collect(Collectors.joining(","));
            collect = "[" + collect + "]";
        }

        if (ObjectUtil.isNotEmpty(userId)) {
            for (String s : userId) {
                //先判断当前要加数据是否已有数据。
                QueryWrapper<UserRelationEntity> userRelationEntityQueryWrapper = new QueryWrapper<>();
                userRelationEntityQueryWrapper.lambda().eq(UserRelationEntity::getObjectType, "Area").eq(UserRelationEntity::getUserId, s).eq(UserRelationEntity::getObjectId, collect.replaceAll(" ", ""));
                UserRelationEntity one = userRelationService.getOne(userRelationEntityQueryWrapper);
                if (ObjectUtil.isNotEmpty(one)) {
                    continue;
                }
                String mainId = RandomUtil.uuId();
                userRelationEntity.setUserId(s);
                userRelationEntity.setId(mainId);
                userRelationEntity.setObjectType("Area");
                userRelationEntity.setObjectId(collect.replaceAll(" ", ""));
                userRelationEntity.setCreatorUserId(userInfo.getUserId());
                userRelationEntity.setCreatorTime(DateUtil.getNowDate());
                userRelationService.save(userRelationEntity);
            }
        }
        return userRelationEntity;
    }

    @Override
    public List<UserRelationEntity> getListByUserId(String userId) {
        return getListByUserIdAll(Collections.singletonList(userId));
    }

    @Override
    public List<UserRelationEntity> getListByUserIdAndObjType(String userId, String objectType) {
        QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
        query.lambda().in(UserRelationEntity::getUserId, userId);
        query.lambda().in(UserRelationEntity::getObjectType, objectType);
        query.lambda().orderByAsc(UserRelationEntity::getSortCode).orderByDesc(UserRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<UserRelationEntity> getListByUserIdAll(List<String> userId) {
        if (userId.size() > 0) {
            QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(UserRelationEntity::getUserId, userId);
            return this.list(queryWrapper);
        }
        return new ArrayList<>();
    }

    @Override
    public List<UserRelationEntity> getListByObjectId(String objectId) {
        return getListByObjectId(objectId, null);
    }

    @Override
    public List<UserRelationEntity> getListByObjectId(String objectId, String objectType) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getObjectId, objectId);
        if (objectType != null) {
            queryWrapper.lambda().eq(UserRelationEntity::getObjectType, objectType);
        }
        queryWrapper.lambda().orderByAsc(UserRelationEntity::getSortCode).orderByDesc(UserRelationEntity::getCreatorTime);
        return this.list(queryWrapper);
    }
    @Override
    public List<UserRelationEntity> getListByUserIdAndObjectId(String userId,String objectId, String objectType) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getUserId, userId);
        queryWrapper.lambda().eq(UserRelationEntity::getObjectId, objectId);
        if (objectType != null) {
            queryWrapper.lambda().eq(UserRelationEntity::getObjectType, objectType);
        }
        queryWrapper.lambda().orderByAsc(UserRelationEntity::getSortCode).orderByDesc(UserRelationEntity::getCreatorTime);
        return this.list(queryWrapper);
    }
    @Override
    public List<UserRelationEntity> getListByObjectIdAll(List<String> objectId) {
        List<UserRelationEntity> list = new ArrayList<>();
        if (objectId.size() > 0) {
            QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(UserRelationEntity::getObjectId, objectId);
            list = this.list(queryWrapper);
        }
        return list;
    }

    @Override
    public void deleteAllByObjId(String objId) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getObjectId, objId);
        this.remove(queryWrapper);
    }

    @Override
    public void deleteAllByUserId(String userId) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getUserId, userId).ne(UserRelationEntity::getObjectType,"Area");
        userRelationService.remove(queryWrapper);
    }

    @Override
    public UserRelationEntity getInfo(String id) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    @DSTransactional
    public void save(String objectId, List<UserRelationEntity> entitys) {
        List<UserRelationEntity> existList = this.getListByObjectId(objectId);
        List<UserRelationEntity> relationList = new ArrayList<>();
        for (int i = 0; i < entitys.size(); i++) {
            UserRelationEntity entity = entitys.get(i);
            entity.setId(RandomUtil.uuId());
            entity.setSortCode(Long.parseLong(i + ""));
            entity.setCreatorUserId(userProvider.get().getUserId());
            if (existList.stream().filter(t -> t.getUserId().equals(entity.getUserId())).count() == 0) {
                relationList.add(entity);
            }
        }
        for (UserRelationEntity entity : relationList) {
            this.save(entity);
        }
    }

    @Override
    public Boolean judgeAuthorize(List<String> address, String userId) {
        String[] addressStr = address.toArray(new String[]{});
        List<String> listOne = new ArrayList<>();
        for (String s : addressStr) {
            listOne.add(s);
        }
        //首先判断当前所选择地址是否是二级，如果是二级地址，则需要查询当前一级地址权限人。
        //比如河南郑州，也要查询河南省的权限跟踪人
        List<UserRelationEntity> listTwo = new ArrayList<>();
        if (listOne.size() > 1) {
            String str =listOne.get(0);
            str = "[\"" + str + "\"]";
            listTwo= userRelationService.getListByObjectId(str.replaceAll(" ", ""), "Area");
        }
        String collect = listOne.stream().map((s) -> "\"" + s + "\"").collect(Collectors.joining(", "));
        collect = "[" + collect + "]";
        List<UserRelationEntity> list = userRelationService.getListByObjectId(collect.replaceAll(" ", ""), "Area");
        if (ObjectUtil.isNotEmpty(listTwo)){
            list.addAll(listTwo);
        }
        boolean flag=false;
        for (UserRelationEntity userRelationEntity : list) {
            if (userRelationEntity.getUserId().equals(userId)) {
                flag=true;
            }
        }
        return flag;
    }

    @Override
    public void save(List<UserRelationEntity> list) {
        for (UserRelationEntity entity : list) {
            this.save(entity);
        }
    }

    @Override
    @DSTransactional
    public void delete(String[] ids) {
        for (String item : ids) {
            QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(UserRelationEntity::getId, item);
            this.remove(queryWrapper);
        }
    }


    @Override
    @DSTransactional
    public void saveObjectId(String objectId, UserRelationForm userRelationForm) {
        // 修改前的岗位绑定人员ID
        List<String> beforeUserIds = userRelationService.getListByObjectId(objectId).stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
        //清除原有成员数据
        deleteAllByObjId(objectId);
        UserInfo userInfo = userProvider.get();
        List<UserRelationEntity> list = new ArrayList<>();
        int i = 0;
        for (String userId : userRelationForm.getUserIds()) {
            UserRelationEntity entity = new UserRelationEntity();
            entity.setId(RandomUtil.uuId());
            entity.setSortCode(Long.parseLong(i + ""));
            entity.setObjectId(objectId);
            entity.setObjectType(userRelationForm.getObjectType());
            entity.setCreatorUserId(userInfo.getUserId());
            entity.setUserId(userId);
            list.add(entity);
            i++;
        }
        save(objectId, list);

        // 并集：所有未修改的人员
        List<String> unUpdateUserId = beforeUserIds.stream().filter(b -> userRelationForm.getUserIds().contains(b)).collect(Collectors.toList());
        // 差集：所有修改过的人员(包括：删除此岗位、添加此岗位的人员)
        beforeUserIds.addAll(userRelationForm.getUserIds());
        List<String> allUpdateIds = beforeUserIds.stream().filter(u -> !unUpdateUserId.contains(u)).collect(Collectors.toList());

        if (PermissionConst.POSITION.equals(userRelationForm.getObjectType())) {
            // 自动切换岗位
            organizeRelationService.autoSetPosition(allUpdateIds);
        }
    }

    @Override
    public void roleSaveByUserIds(String roleId, List<String> userIds) {
        //清除原有成员数据
        deleteAllByObjId(roleId);
        String currentUserId = userProvider.get().getId();
        List<UserRelationEntity> userRelationList = new ArrayList<>();
        for (String userId : userIds) {
            UserRelationEntity entity = new UserRelationEntity();
            entity.setId(RandomUtil.uuId());
            entity.setObjectId(roleId);
            entity.setObjectType(PermissionConst.ROLE);
            entity.setCreatorUserId(currentUserId);
            entity.setUserId(userId);
            userRelationList.add(entity);
        }
        this.saveBatch(userRelationList);
    }

    @Override
    public List<UserRelationEntity> getListByObjectType(String userId, String objectType) {
        QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(UserRelationEntity::getUserId, userId).eq(UserRelationEntity::getObjectType, objectType);
        query.lambda().orderByAsc(UserRelationEntity::getSortCode).orderByDesc(UserRelationEntity::getCreatorTime);
        return this.list(query);
    }

    @Override
    public List<UserRelationEntity> getAllOrgRelationByUserId(String userId) {
        return this.getListByObjectType(userId, PermissionConst.ORGANIZE);
    }
    /**
     * 获取个人信息页面用户组织/岗位/角色集合
     *
     * @param objectType 归属类型
     */
    @Override
    public List<PermissionModel> getObjectVoList(String objectType) {
        String userId = userProvider.get().getUserId();
        UserEntity userEntity = userService.getInfo(userId);
        String majorOrgId = userProvider.get().getDepartmentId();

        // 组装对应组织/岗位/角色对象
        switch (objectType) {
            case PermissionConst.ORGANIZE:
                // 使用in查询减少数据库查询次数
                List<String> ids = new ArrayList<>();
                this.getListByObjectType(userId, objectType).forEach(r -> ids.add(r.getObjectId()));
                List<PermissionModel> permissionModels = setModel(organizeService.getOrgEntityList(ids, false), majorOrgId);
                permissionModels.forEach(p -> p.setFullName(PermissionUtil.getLinkInfoByOrgId(p.getId(), organizeService, false)));
                return permissionModels;
            case PermissionConst.POSITION:
                // 岗位遵循一对多关系
                List<PositionEntity> positionList = positionService.getListByUserId(userId);
                if (positionList.size() > 0) {
                    return setModel(positionList.stream().filter(p -> p.getOrganizeId().equals(majorOrgId)).collect(Collectors.toList()), userEntity.getPositionId());
                }
            default:
                return null;
        }
    }
    /**
     * 根据用户id获取个人信息页面用户组织/岗位/角色集合
     * @param id 用户id
     * @param objectType 归属类型
     */
    @Override
    public List<PermissionModel> getObjectVoListById(String id,String objectType) {
        String userId = id;
        UserEntity userEntity = userService.getInfo(userId);
        String majorOrgId = userEntity.getOrganizeId();

        // 组装对应组织/岗位/角色对象
        switch (objectType) {
            case PermissionConst.ORGANIZE:
                // 使用in查询减少数据库查询次数
                List<String> ids = new ArrayList<>();
                this.getListByObjectType(userId, objectType).forEach(r -> ids.add(r.getObjectId()));
                List<PermissionModel> permissionModels = setModel(organizeService.getOrgEntityList(ids, false), majorOrgId);
                permissionModels.forEach(p -> p.setFullName(PermissionUtil.getLinkInfoByOrgId(p.getId(), organizeService, false)));
                return permissionModels;
            case PermissionConst.POSITION:
                // 岗位遵循一对多关系
                List<PositionEntity> positionList = positionService.getListByUserId(userId);
                if (positionList.size() > 0) {
                    return setModel(positionList.stream().filter(p -> p.getOrganizeId().equals(majorOrgId)).collect(Collectors.toList()), userEntity.getPositionId());
                }
            default:
                return null;
        }
    }
    /**
     * 设置返回模型
     *
     * @param permissionList
     * @param majorId
     */
    public <T extends PermissionEntityBase> List<PermissionModel> setModel(List<T> permissionList, String majorId) {
        List<PermissionModel> voList = new ArrayList<>();
        permissionList.forEach(p -> {
            PermissionModel model = new PermissionModel();
            if (p.getId().equals(majorId)) {
                model.setIsDefault(true);
            } else {
                model.setIsDefault(false);
            }
            model.setFullName(p.getFullName());
            model.setId(p.getId());
            model.setFullName(p.getFullName());
            voList.add(model);
        });
        return voList;
    }

    @Override
    public Boolean existByObjectId( String objectId,String objectType) {
        QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(UserRelationEntity::getObjectType, objectType).eq(UserRelationEntity::getObjectId, objectId);
        return this.count(query) > 0;
    }

    @Override
    public List<UserRelationEntity> getListByRoleId(String roleId) {
        List<UserRelationEntity> list = new ArrayList<>();
        organizeRelationService.getRelationListByRoleId(roleId).forEach(o -> {
            QueryWrapper<UserRelationEntity> query = new QueryWrapper<>();
            query.lambda().eq(UserRelationEntity::getObjectType, PermissionConst.ORGANIZE)
                    .eq(UserRelationEntity::getObjectId, o.getOrganizeId());
            list.addAll(this.list(query));
        });
        return list;
    }

    @Override
    public List<UserRelationEntity> getListByRoleIds(String roleId) {
        List<UserRelationEntity> list =  userRelationService.getListByObjectId(roleId);
        return list;
    }

    @Override
    public List<UserRelationEntity> getListByUserId(String userId, String objectType) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getUserId, userId);
        queryWrapper.lambda().eq(UserRelationEntity::getObjectType, objectType);
        return this.list(queryWrapper);
    }

    @Override
    public List<UserRelationEntity> getListByOrgId(List<String> orgIdList) {
        QueryWrapper<UserRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRelationEntity::getObjectType, PermissionConst.ORGANIZE);
        if (CollectionUtil.isNotEmpty(orgIdList)) {
            queryWrapper.lambda().in(UserRelationEntity::getObjectId, orgIdList);
        }
        return this.list(queryWrapper);
    }

    @Override
    public String getAllOrganizeNameInfoById(String id) {
        List<UserRelationEntity> orgRelationListByUserId = userRelationService.getAllOrgRelationByUserId(id);
        StringBuilder organize = new StringBuilder();
        String organizeName = "";
        for (UserRelationEntity userRelationEntity : orgRelationListByUserId) {
            // 获取组织id详情
            OrganizeEntity entity = organizeService.getInfo(userRelationEntity.getObjectId());
            if (entity != null) {
                // 获取到组织树
                String organizeIdTree = entity.getOrganizeIdTree();
                if (StringUtils.isNotEmpty(organizeIdTree)) {
                    // 获取到组织id集合
                    String[] orgId = organizeIdTree.split(",");
                    List<OrganizeEntity> organizeNameList = organizeService.getOrganizeNameSort(Arrays.asList(orgId));
                    // 单个组织储存在这里
                    StringBuilder orgName = new StringBuilder();
                    for (OrganizeEntity organizeEntity : organizeNameList) {
                        orgName.append("/" + organizeEntity.getFullName());
                    }
                    if (orgName.length() > 0) {
                        organize.append(";" + orgName.toString().replaceFirst("/", ""));
                    }
                }
            }
        }
        if (organize.length() > 0) {
            organizeName = organize.toString().replaceFirst(";", "");
        }
        return organizeName;
    }

}
